using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static Player;

public class MapManager : MonoBehaviour
{
    public static MapManager instance;

    public GameObject mapBlock;
    public GameObject currentMapBlock;
    public List<GameObject> createBlocks = new List<GameObject>();
    public List<GameObject> blocks = new List<GameObject>();
    public float destroyDis = 20f;
    public Player player;

    private void Awake()
    {
        instance = this;
        CreateMapBlock();
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void CreateMapBlock()
    {
        
        for (int i = 0; i < 16; i++)
        {
            GameObject map = GameObject.Instantiate(mapBlock);
            map.transform.parent = this.transform;
            map.SetActive(false);
            blocks.Add(map);
        }
    }

    public bool CheckExistMap(Vector3 target)
    {
        if (!Physics2D.OverlapCircle(target, 1.5f, LayerMask.GetMask("MapBlock")))
        {
            return true;
        } else
        {
            return false;
        }
    }

    public void GetTargetBlockFromDir(Vector3 triggerPos, MoveDirEnum dir)
    {
        Vector3 targetPos = Vector3.zero;

        switch (dir)
        {
            case MoveDirEnum.up:
                targetPos = triggerPos + new Vector3(0, 20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.down:
                targetPos = triggerPos + new Vector3(0, -20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.left:
                targetPos = triggerPos + new Vector3(-20, 0, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.right:
                targetPos = triggerPos + new Vector3(20, 0, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.leftUp:
                targetPos = triggerPos + new Vector3(-20, 20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.leftDown:
                targetPos = triggerPos + new Vector3(-20, -20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.rightUp:
                targetPos = triggerPos + new Vector3(20, 20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
            case MoveDirEnum.rightDown:
                targetPos = triggerPos + new Vector3(20, -20, 0);
                if (CheckExistMap(targetPos))
                {
                    SetMapBlockPosition(dir);
                }
                break;
        }
    }

    public void SetMapBlockPosition(MoveDirEnum dir)
    {
        Vector3 nowOffset = Vector3.zero;
        switch (dir)
        {
            case MoveDirEnum.up:
                nowOffset = new Vector3(0, 20, 0);
                break;
            case MoveDirEnum.down:
                nowOffset = new Vector3(0, -20, 0);
                break;
            case MoveDirEnum.left:
                nowOffset = new Vector3(-20, 0, 0);
                break;
            case MoveDirEnum.right:
                nowOffset = new Vector3(20, 0, 0);
                break;
            case MoveDirEnum.leftUp:
                nowOffset = new Vector3(-20, 20, 0);
                break;
            case MoveDirEnum.leftDown:
                nowOffset = new Vector3(-20, -20, 0);
                break;
            case MoveDirEnum.rightUp:
                nowOffset = new Vector3(20, 20, 0);
                break;
            case MoveDirEnum.rightDown:
                nowOffset = new Vector3(20, -20, 0);
                break;
        }
        GameObject mapBlock = GetBlocks();
        if(mapBlock != null)
        {
            mapBlock.transform.position = currentMapBlock.transform.position + nowOffset;
            createBlocks.Add(mapBlock);
        }

    }

    public void CheckAllDir(Transform tf)
    {
        GetTargetBlockFromDir(tf.position, MoveDirEnum.up);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.down);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.left);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.right);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.leftUp);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.leftDown);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.rightUp);
        GetTargetBlockFromDir(tf.position, MoveDirEnum.rightDown);
    }

    public void CollectMapBlocks()
    {
        List<GameObject> list = new List<GameObject>();
        if(createBlocks.Count > 0)
        {
            for (int i = 0; i < createBlocks.Count; i++)
            {
                if (Vector3.Distance(player.transform.position, createBlocks[i].transform.position) >= destroyDis)
                {
                    GameObject map = createBlocks[i];
                    list.Add(map);
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                GameObject map = list[i];
                blocks.Add(map);
                map.transform.parent = this.transform;
                map.transform.localPosition = Vector3.zero;
                map.SetActive(false);
                createBlocks.Remove(map);
            }
        }
    }

    public GameObject GetBlocks()
    {
        GameObject go = null;
        if(blocks.Count > 0)
        {
            go = blocks.Find(a => !a.activeInHierarchy);
            go.SetActive(true);
            go.transform.parent = null;

            blocks.Remove(go);
            return go;
        } else
        {
            return null;
        }
    }
}
